<title>hello my shar</title>
<xmp style="display: none;">
## snippetclient
html片段客户端管理，从http服务读取片段并渲染到页面。

- 业务层 -> 渲染层 -> 浏览器
- 在哪个层面进行渲染?
- 同步渲染还是异步渲染？
- 如何不增加性能负担？
- 什么时候更新？

### 例子
[库地址-gitbook](http://doc.wuage-fe.com/components/common/snippetclient.html)
```js
import client from '@wag/snippetclient'
// 注册
const url = 'https://xxxxxx'
//如果是dvm
const dvmURL = client.fromDvm(appName,group,name)
client.register(url)
client.register(dvmURL)
something......
function render(args){
  // 使用
  const xx = client.getSnippet(url)
  // 如果是velocity片段
  const xx = client.parseWithVelocity(context, dvmURL)
}
```
### 更新
1. 访问页面触发
2. 定时一分钟后更新到内存（client内的状态变量）
   - 判断client状态已经正在更新（避免重复更新）
3. 渲染的时候直接拿状态变量中的片段

##### `Q&A`


## velocity macro combo
给岁月以文明，而不是给文明以岁月！

- 如何快速拼接静态资源为combo方式?
  - `//static.wuage.com/??a.js,b.js`
- 如何快速在测试，预发，线上 等环境 安全的将静态资源指向本地？


## comboresource.vm
[https://dvm.wuage.com/dvm/templet/operatetemplet?templetId=55](https://dvm.wuage.com/dvm/templet/operatetemplet?templetId=55)
### url
```
#cscript([
  "a.js"
])
输出  <script src="//static.wuage.com/a.js"></script>
```
### url
```
#cscript([
  "a.js",
  "b.js"
])
输出 <script src="//static.wuage.com/??a.js,b.js"></script>
```
### url?cdebug=7766
```
#cscript([
  "a.js",
  "b.js"
])
输出
<script src="http://dev7.wuage.com:7766/a.js"></script>
<script src="http://dev7.wuage.com:7766/b.js"></script>
```
### 使用chrome访问的时候 只需要点击加载不安全脚本一次就可以了
## 源码片段
```html
#set ($cdebug_ = $request.getParameter("cdebug"))
#set ($demon_7 = "static.wuage.com")
#macro(cscript $xs)
  #if($xs.size() == 1)
    #if($cdebug_)
      <script src="http://dev7.wuage.com:$!cdebug_/$xs.get(0)"></script>
    #else
      <script src="//$demon_7/$xs.get(0)"></script>
    #end
  #else
    #if($cdebug_)
      #foreach($x in $xs)
        <script src="http://dev7.wuage.com:$!cdebug_/$x"></script>
      #end
    #else
      #set ($jssp = "")
      #set ($jsstr = "")
      #foreach($x in $xs)
        #set ($jsstr = "$jsstr$jssp$x")
        #set ($jssp = ",")
      #end
      <script src="//$demon_7/??$jsstr" ></script>
    #end
  #end
#end
```

##### `Q&A`

## 函数式程序中的概念
从大的方面了解函数式程序，由于点比较多所以都是点到为止！！

## 1. 表达式 VS 语句

- 没有循环
- 没有分支
- 没有语句
- 执行顺序是不定的


### 语句
```javascript
let n = null
if(cond){
  n = -1
}else{
  n = 1
}
```
### 表达式
```
n = if cond then -1 else 1
```

## 2. 不可变数据 VS 可变数据

- 可靠性
- 多线程

### 可变数据方式
```
function sum(xs){
  let r = 0
  for(let i=0;i<xs.length;i++){
    r += xs[i]
  }
  return r
}
```
### 不可变数据方式
```
sum [] = 0
sum (x:xs) = x + sum xs
```

## 3. 纯函数
即相同的输入，永远会得到相同的输出，而且没有任何可观察的副作用

- 可缓存性
- 可移植性／自文档化
- 可测试性
- 并行代码

### 可缓存性示例
```
let fib = n => n == 0 ? 0
: n == 1              ? 1
: fib(n-1) + fib(n-2)
```
### 缓存后的fib
```
function memorize(fn){
  let cache = {}
  return function(n){
    if(cache[n] != null){
      return cache[n]
    }else{
      cache[n] = fn(n)
      return cache[n]
    }
  }
}
let fib = memorize(n=> n == 0 ? 0
: n == 1                      ? 1
: fib(n-1) + fib(n-2))
```

## 4. 一切皆函数与有趣的中缀函数
即函数在中间，参数在两边。这让我想起一句话 一生二，二生三，三生万物!!! O(∩_∩)O~

### 常见的中缀函数
`+   - * /`  当然在js中这些只是操作符并没有函数的特性（可传递）
### 假如有以下函数
```
fucntion toCall(a,fn){
  return fn(a)
}
// sum 对数组进行求和
// take2 取出前2个元素
toCall(toCall([1,2,3], take2,sum)
```
### 如果可以写成中缀的形式
```
[1,2,3] toCall take2 toCall sum
```
## 出于美观的考虑把函数名字改为 |>
```
[1,2,3] |> take2 |> sum
```

## 5. currying 与 pointfree
将一个函数的多个参数转化为一个参数 （一般在函数式语言中所有的函数默认都是curry的）

### 假如take函数是currying的
```
// 取出xs中前n个元素
function take(n,xs){
  something...
}
[1, 2, 3] |> take(2) |> sum
```
:start
### js中curry的实现
```
function partial(fn,args){
  return function(){
     var nargs = [].slice.call(arguments)
     return fn.apply(null,args.concat(nargs))
  }
}

function curryN(fn,n){
  return function(){
     var args = [].slice.call(arguments)
     if(n <= args.length ) return fn.apply(null,args)
     return curryN(partial(fn,args),n-args.length)
  }
}

function curry(fn){
  return curryN(fn,fn.length)
}

//使用示例
var mul = curry(function (a,b,c){
  return a * b * c
})
```
:end

## 6. 惰性求值

:start
## 特色
- 代码优化（主要给编译器：抵消相同项从⽽避免执⾏⽆谓的代码，安排代码执⾏顺序）
- 抽象化控制结构 （类似js中的表达式 `cond && something code....`）
- ⽆穷数据结构
## 自然数的表达code
表达10以内的自然数我们可以这样
```
let ns = [0,1,2,3,4,5,6,7,8,9]
```
但表达自然数这个在非惰性求值的数据结构上面是完成不了的

需要自己创造惰性数据类型
```
let ns = cons(0,map(a=>a+1))
```
[这个里面有实现好的惰性序列例子](http://www.diqye.com/fibonacci.html?inner=share)

## 对文件的读取写入问题
```
let fs = require('fs')
let content = await fs.readFile(your/file/path)
fs.writeFile(yout/file/path,content)
```
如果文件体积过大 会导致内存溢出错误。

但如果是惰性的string类型会正常运行。

因为惰性只有在使用到的时候才会进行读取并进行合理分段处理
:end

## 7.类型系统与模式匹配
跟java,js,c 这类语言的类型有所不同，使用模式匹配进行配套的解析

- 无NULL值
- 无运行时异常
- 可类型参数(有点类似java中的泛型)
- 类型推导

### Bool类型
```
data Bool = True | False
-- expression
bstr = case True of True -> "true"
                    Fasle -> "false"
```
### Maybe
```
data Maybe a = Nothing | Just a
-- expression
mstr = case (Just 1) of Nothing -> "xxx"
                        (Just n) -> "nnn"
```

## 8. monad与cps

- 执行顺序控制
- 样板代码的抽象

# CPS

:start
```
let a = something....
if(a != null){
  let b = something(b)
  if(b != null){
    return b
  }else{
    return null
  }
}else{
  return null
}
```
### CPS方式
```
function nullCPS(a,nextfn){
  if(a == null){
    return null
  }else{
    return nextfn(a)
  }
}

nullCPS(something..,function(a){
  return nullCPS(something(a),function(b){
     return b
  })
})

// 如果为cps添加语法糖
nullCPS(
  a <- something...
  b <- something(b)
  return b
)
```
:end

### monad(单子)
[一个 Monad 说白了不过就是自函子范畴上的一个幺半群而已](http://hongjiang.info/understand-monad-4-what-is-functor/)

### functor(函子) -> applicative(应用函子) -> monad
### 在数据类型上如果实现下面列表就可以成为monad了
- return :: a -> m a (略过)
- (>>=) 或者 bind :: m a -> (a -> m b) -> m b
- join  :: m (m a) -> m a (略过)
- [需要满足的定律](http://www.diqye.com/moand.html)
```
return something... >>= \a -> something b
-- 换成语法糖
do
  a <- something...
  b <- something a
  return b
```

## 元编程
在编译阶段生成代码，运行阶段执行

### jsx
```
render(
  <div>hello</div>
)
```
### 如果支持元编程 就不需要构建工具了
```
macro render(syntax){
  let jscode = something...
  return jscode
}
render(<div>hello</div>)
```

## 缺点

- 难于debug
- 性能依赖编译器

##### `Q&A`
![qcode](http://www.diqye.com/img/zhifubao.png)

</xmp>
<script src="../lib/impt.js" main="./app.js"></script>
